package smoker.client;

import java.io.*;
import java.net.*;
import smoker.tools.*;

public class Client implements IClient, Runnable {
	private boolean isRunning = true;
	private Socket socket;
	private String serverIP;
	private int port;
	private IClientCenter iClientCenter;
	
	public Client(IClientCenter iClientCenter) {
		this.iClientCenter = iClientCenter;
	}

	public boolean connServer() {
		try {
			serverIP = iClientCenter.getServerIP();
			port = iClientCenter.getPort();
			socket = new Socket(serverIP, port);
		}catch (Exception e) {
			return false;
		}
		new Thread(this).start();
		return true;
	}
	
	public boolean isSocketConnection() {
		if(socket.isConnected() == true) {
			return true;
		}else {
			return false;
		}
	}
	
	public void run() {
		InputStream is;
		try {
			is = socket.getInputStream();
			while(isRunning) {
				if(is.available() > 0) {
					handleInputStream(is);
				}
				Thread.sleep(999);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void handleInputStream(InputStream is) {
		try {
			ObjectInputStream ois = new ObjectInputStream(is);
			Message message = (Message)ois.readObject();
			handleMessage(message);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void handleMessage(Message message) {
		int type = message.getType();
		switch (type) {
		case MsgType.TYPE_LOGIN:
			RadiateData receiveRD = (RadiateData)message.getData();
			iClientCenter.onLoginResult(receiveRD);
			break;
		case MsgType.TYPE_CHAT:
			ChatInfo chatMsg = (ChatInfo)message.getData();
			iClientCenter.reciveMessage(chatMsg);
			break;
		case MsgType.TYPE_ONLINE:
			User onLineUser = (User)message.getData();
			iClientCenter.onLineInfromAboutAllUser(onLineUser);
			break;
		case MsgType.TYPE_OFFLINE:
			User offLineUser = (User)message.getData();
			iClientCenter.delOffLineUserNode(offLineUser);
			break;
		case MsgType.TYPE_EXIST:
			iClientCenter.theUserIsExist();
			break;
		case MsgType.TYPE_CLOSE:
			iClientCenter.closeClient();
			break;
		case MsgType.YTPE_UPDATEOK:
			iClientCenter.onUpdateResult(MsgType.YTPE_UPDATEOK);
			break;
		case MsgType.TYPE_COERCEOFFLINE:
			iClientCenter.coerceOffLine();
			break;
		}
	}
	
	public void sendMessage(Message message) {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
			oos.writeObject(message);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void login(User user) {
		Message message = new Message(MsgType.TYPE_LOGIN, user);
		sendMessage(message);
	}

	public void offLineAndCloseSocket() {
		try {
			isRunning = false;
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void updateUser(User user) {
		sendMessage(new Message(MsgType.TYPE_UPDATE, user));
	}
}
